namespace OneWorks.Utils.FluentData
{
    using System;
    using System.Linq.Expressions;

    internal class UpdateBuilder<T> : BaseUpdateBuilder, IUpdateBuilder<T>, IInsertUpdateBuilder<T>
    {
        public T Item { get; private set; }

        internal UpdateBuilder(IDbProvider provider, IDbCommand command, string name, T item)
            : base(provider, command, name)
        {
            this.Data.Item = item;
            this.Item = item;
        }

        public IUpdateBuilder<T> Column(string columnName, object value, DataTypes parameterType, int size)
        {
            this.Actions.ColumnValueAction(columnName, value, parameterType, size);
            return this;
        }

        public IUpdateBuilder<T> AutoMap(params Expression<Func<T, object>>[] ignoreProperties)
        {
            this.Actions.AutoMapColumnsAction(ignoreProperties);
            return this;
        }

        public IUpdateBuilder<T> Column(Expression<Func<T, object>> expression, DataTypes parameterType, int size)
        {
            this.Actions.ColumnValueAction(expression, parameterType, size);
            return this;
        }

        public virtual IUpdateBuilder<T> Where(string columnName, object value, DataTypes parameterType, int size)
        {
            this.Actions.WhereAction(columnName, value, parameterType, size);
            return this;
        }

        public IUpdateBuilder<T> Where(Expression<Func<T, object>> expression, DataTypes parameterType, int size)
        {
            this.Actions.WhereAction(expression, parameterType, size);
            return this;
        }

        IInsertUpdateBuilder<T> IInsertUpdateBuilder<T>.Column(string columnName, object value, DataTypes parameterType, int size)
        {
            this.Actions.ColumnValueAction(columnName, value, parameterType, size);
            return this;
        }

        IInsertUpdateBuilder<T> IInsertUpdateBuilder<T>.Column(Expression<Func<T, object>> expression, DataTypes parameterType, int size)
        {
            this.Actions.ColumnValueAction(expression, parameterType, size);
            return this;
        }

        public IUpdateBuilder<T> Fill(Action<IInsertUpdateBuilder<T>> fillMethod)
        {
            fillMethod(this);
            return this;
        }
    }

    internal class UpdateBuilder : BaseUpdateBuilder, IUpdateBuilder, IInsertUpdateBuilder
    {
        internal UpdateBuilder(IDbProvider dbProvider, IDbCommand command, string name)
            : base(dbProvider, command, name)
        {
        }

        public virtual IUpdateBuilder Where(string columnName, object value, DataTypes parameterType, int size)
        {
            this.Actions.WhereAction(columnName, value, parameterType, size);
            return this;
        }

        public IUpdateBuilder Column(string columnName, object value, DataTypes parameterType, int size)
        {
            this.Actions.ColumnValueAction(columnName, value, parameterType, size);
            return this;
        }

        IInsertUpdateBuilder IInsertUpdateBuilder.Column(string columnName, object value, DataTypes parameterType, int size)
        {
            this.Actions.ColumnValueAction(columnName, value, parameterType, size);
            return this;
        }

        public IUpdateBuilder Fill(Action<IInsertUpdateBuilder> fillMethod)
        {
            fillMethod(this);
            return this;
        }
    }
}